package com.rain.cy.business.service;

import com.rain.cy.business.constant.CommonConstant;
import com.rain.cy.business.model.dto.UserProcessStatusDTO;
import com.rain.cy.business.model.entity.CommonProcessEntity;
import com.rain.cy.business.model.entity.UserProcessStatusEntity;
import com.rain.cy.business.mapper.UserProcessStatusMapper;
import com.rain.cy.framework.entity.impl.BaseServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author yuchen
 * @since 2021-10-02
 */
@Service
public class UserProcessStatusService extends BaseServiceImpl<UserProcessStatusMapper, UserProcessStatusEntity> {
    @Autowired
    private CommonProcessService commonProcessService;

    @Autowired
    private UserProcessStatusService userProcessStatusService;


    /**
     * 更新用户进程
     *
     * @param userId
     * @param processIds
     * @return
     */
    public void updateUserProcessStatus(Integer userId, String... processIds) {
        UserProcessStatusEntity processStatusEntity = getAndInitUserProcessStatus(userId);
        for (String processId : processIds) {
            processStatusEntity.getProcessStatusData().put(processId, 1);
        }
        userProcessStatusService.saveOrUpdate(processStatusEntity);
    }

    public void updateUserProcessStatusForDisable(Integer userId, String... processIds) {
        UserProcessStatusEntity processStatusEntity = getAndInitUserProcessStatus(userId);
        for (String processId : processIds) {
            processStatusEntity.getProcessStatusData().put(processId, 0);
        }
        userProcessStatusService.saveOrUpdate(processStatusEntity);
    }


    /**
     * 获取当前最新的用户进程
     *
     * @param userId
     * @return
     */
    public Integer getCurrentProcess(Integer userId) {
        UserProcessStatusEntity userProcessStatusEntity = getAndInitUserProcessStatus(userId);
        Map<String, Integer> processStatusData = userProcessStatusEntity.getProcessStatusData();
        return processStatusData.keySet()
                .stream().filter(s -> s.length() == 2 && processStatusData.get(s) == 1)
                .map(Integer::parseInt)
                .map(integer -> integer / 10)
                .max(Comparator.comparingInt(o -> o)).orElse(2);
    }

    /**
     * 构建用户的进程树
     *
     * @param userProcessStatusEntity
     * @return
     */
    public List<UserProcessStatusDTO> buildTree(UserProcessStatusEntity userProcessStatusEntity) {
        List<UserProcessStatusDTO> userProcessStatusDTOList = buildUserProcessStatusList(userProcessStatusEntity);
        List<UserProcessStatusDTO> processStatusDTOList = userProcessStatusDTOList.stream()
                .filter(processStatus -> processStatus.getProcessId().length() == 2)
                .collect(Collectors.toList());

        List<UserProcessStatusDTO> children = userProcessStatusDTOList.stream()
                .filter(processStatus -> processStatus.getProcessId().length() == 4)
                .collect(Collectors.toList());

        for (UserProcessStatusDTO userProcessStatusDTO : processStatusDTOList) {
            List<UserProcessStatusDTO> childrenList = children.stream().filter(s -> s.getProcessId().startsWith(userProcessStatusDTO.getProcessId())).collect(Collectors.toList());
            userProcessStatusDTO.getChildren().addAll(childrenList);
        }
        return processStatusDTOList;
    }

    private List<UserProcessStatusDTO> buildUserProcessStatusList(UserProcessStatusEntity userProcessStatusEntity) {
        Map<String, Integer> processStatusDataMap = userProcessStatusEntity.getProcessStatusData();
        List<CommonProcessEntity> commonProcessEntities = commonProcessService.lambdaQuery().orderByAsc(CommonProcessEntity::getParentId).list();
        return commonProcessEntities.stream().map(UserProcessStatusDTO::from)
                .peek(userProcessStatusDTO -> userProcessStatusDTO.setProcessStatus(processStatusDataMap.getOrDefault(userProcessStatusDTO.getProcessId(), 0)))
                .collect(Collectors.toList());
    }

    /**
     * 初始化用户进度数据
     *
     * @param userId 患者ID
     * @return
     */
    public UserProcessStatusEntity getAndInitUserProcessStatus(Integer userId) {
        UserProcessStatusEntity processStatusEntity = lambdaQuery().eq(UserProcessStatusEntity::getUserId, userId).last("limit 1").one();
        if (processStatusEntity != null) {
            return processStatusEntity;
        }
        List<CommonProcessEntity> commonProcessEntityList = commonProcessService.lambdaQuery().orderByAsc(CommonProcessEntity::getParentId).list();
        Map<String, Integer> collect = commonProcessEntityList.stream()
                .collect(Collectors.toMap(CommonProcessEntity::getId,
                        commonProcessEntity -> (commonProcessEntity.getId().startsWith(CommonConstant.PROCESS_ID_ONE) || commonProcessEntity.getId().equals(CommonConstant.PROCESS_ID_TWO)) ? 1 : 0)
                );
        UserProcessStatusEntity userProcessStatusEntity = new UserProcessStatusEntity();
        userProcessStatusEntity.setUserId(userId);
        userProcessStatusEntity.setProcessStatusData(collect);
        boolean b = userProcessStatusService.saveOrUpdate(userProcessStatusEntity);
        return userProcessStatusEntity;
    }
}
